<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="echarts.js"></script>
</head>
<body>
    <button onclick="handleClick();">开始编译指定代码</button>
    <div style="width: 100%; height: 500px; margin: 16px; display: flex;">
        <textarea id="textarea" style="height: 100%; width: 40%; border: 1px solid black;" spellcheck="false"></textarea>
        <div id="main" style="height: 500px; width: 60%;"></div>
    </div>
    <div id="tokens" style="height: 200px; width: 100%; overflow: scroll;"></div>
    <script>
        function DFS(root, node) {
            for(let child of root.children) {
                let n = {
                    name: child.data,
                    children: []
                }
                node.children.push(n)
                DFS(child, n)
            }
        }

        function handleClick() {
            let textarea = document.getElementById("textarea"), code = textarea.value
            fetch("./analysis", {
                method: "post",
                body: code
            }).then(res => res.text()).then(res => {
                if(res.slice(2, 4) == "错误") {
                    let tokens = document.getElementById("tokens")
                    tokens.innerHTML = res
                }
                else {
                    let {root, tokens, errors} = JSON.parse(res)

                    // 将语法树数据转化为指定格式
                    let treeData = []
                    let node = {
                        name: root.data,
                        children: []
                    }
                    treeData.push(node)
                    DFS(root, node)

                    // 绘制语法树
                    function draw(data) {
                        // 画图前先绑定目标对象
                        let chart = echarts.init(document.querySelector("#main"))
                        let option = {
                            tooltip: {
                                trigger: 'item',
                                triggerOn: 'mousemove'
                            },
                            // 表示数据部分，如果有多个对象，那么表示在一个画板上叠加画图
                            series: [
                                {
                                    type: 'tree',
                                    data: data,
                                    symbol: 'emptyCircle',
                                    expandAndCollapse: false,
                                    label: {
                                        position: 'top',
                                        verticalAlign: 'middle',
                                        align: 'right',
                                        fontSize: 9
                                    },
                                    leaves: {
                                        label: {
                                            position: 'bottom',
                                            verticalAlign: 'middle',
                                            align: 'left'
                                        }
                                    },
                                    animationDurationUpdate: 750
                                }
                            ]
                        }
                        // 绘制
                        chart.setOption(option)
                    }

                    draw(treeData)

                    if(errors == "") {
                        // 如果语法分析没有错误，序列化处理tokens
                        let len = tokens.length
                        for (let i = 0; i < len; i++)
                            tokens[i] = `{ content: ${tokens[i].content}, row: ${tokens[i].row}, col: ${tokens[i].col}, type: ${tokens[i].type} }<br>`
                        tokens = tokens.join("\n")
                        document.querySelector("#tokens").innerHTML = tokens
                    } else {
                        // 如果在语法分析时遇到错误，那么在显示token的位置打印错误
                        let tokens = document.getElementById("tokens")
                        tokens.innerHTML = errors
                    }
                }
            })
        }
    </script>
</body>
</html>